package com.gel.codegeneration.service.impl;
import cn.hutool.core.util.StrUtil;
import com.gel.codegeneration.common.enums.ErrorCode;
import com.gel.codegeneration.common.enums.UserRoleEnum;
import com.gel.codegeneration.convention.exception.BusinessException;
import com.gel.codegeneration.mapper.UserMapper;
import com.gel.codegeneration.model.dto.req.user.UserQueryRequest;
import com.gel.codegeneration.model.dto.resp.user.LoginUserVO;
import com.gel.codegeneration.model.dto.resp.user.UserVO;
import com.gel.codegeneration.model.entity.User;
import com.gel.codegeneration.service.UserService;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.DigestUtils;

import java.util.List;
import java.util.stream.Collectors;

import static com.gel.codegeneration.common.constant.UserConstant.USER_LOGIN_KEY;

/**
 * 用户 服务层实现。
 *
 * @author <a>gel</a>
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>  implements UserService {


    /**
     * @description:用户注册
     * @author: gel
     * @date: 2025/8/21 10:43
     * @param: [userAccount, userPassword, checkPassword]
     * @return: long
     **/
    @Override
    public long register(String userAccount, String userPassword, String checkPassword) {
        //校验
        if(StrUtil.hasBlank(userAccount, userPassword, checkPassword)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"参数为空");
        }
        if(userAccount.length() < 4){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户账号过短");
        }
        if(userPassword.length() < 8 || checkPassword.length() < 8){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户密码过短");
        }
        if(!userPassword.equals(checkPassword)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"两次输入的密码不一致");
        }
        //检查是否重复
        QueryWrapper queryWrapper= new QueryWrapper();
        queryWrapper.eq(User::getUserAccount, userAccount);
        long count = this.mapper.selectCountByQuery(queryWrapper);
        if(count > 0){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"账号重复");
        }
        //加密
        String encryptedPassword = getEncryptedPassword(userPassword);
        //插入数据
        User user = User.builder()
                .userAccount(userAccount)
                .userPassword(encryptedPassword)
                .userName("gel")
                .userRole(UserRoleEnum.USER.getValue())
                .build();
        boolean saveResult = this.save(user);
        if(!saveResult){
            throw new BusinessException(ErrorCode.SYSTEM_ERROR,"注册失败，数据库错误");
        }
        return user.getId();

    }
    /**
     * @description:用户登录
     * @author: gel
     * @param: [userAccount, userPassword, request]
     * @return: com.gel.codegeneration.model.dto.resp.user.LoginUserVO
     **/

    @Override
    public LoginUserVO login(String userAccount, String userPassword, HttpServletRequest request) {
        //校验
        if(StrUtil.hasBlank(userAccount, userPassword)){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"参数为空");
        }
        if(userAccount.length() < 4){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户账号错误");
        }
        if(userPassword.length() < 8){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户密码错误");
        }
        //加密
        String encryptedPassword = getEncryptedPassword(userPassword);
        //查询用户是否存在
        QueryWrapper queryWrapper= new QueryWrapper();
        queryWrapper.eq(User::getUserAccount, userAccount)
                .eq(User::getUserPassword, encryptedPassword);
        User user = this.mapper.selectOneByQuery(queryWrapper);
        if(user == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户不存在或密码错误");
        }
        //记录登录状态
        request.getSession().setAttribute(USER_LOGIN_KEY, user);
        //返回登录信息
        LoginUserVO loginUserVO = new LoginUserVO();
        BeanUtils.copyProperties(user, loginUserVO);
        return loginUserVO;

    }

    @Override
    public User getLoginUser(HttpServletRequest request) {
        Object attribute = request.getSession().getAttribute(USER_LOGIN_KEY);
        User user= (User) attribute;
        if(user == null){
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        return user;
    }

    @Override
    public boolean userLoginOut(HttpServletRequest request) {
        Object attribute = request.getSession().getAttribute(USER_LOGIN_KEY);
        if(attribute == null){
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        request.getSession().removeAttribute(USER_LOGIN_KEY);
        return true;
    }

    @Override
    public UserVO getUseVO(User user) {
        if (user == null){
            return null;
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return userVO;
    }

    @Override
    public List<UserVO> getUserVOList(List<User> userList) {
        if(CollectionUtils.isEmpty(userList)){
            return null;
        }
        return userList.stream()
                .map(this::getUseVO)
                .collect(Collectors.toList());
    }

    @Override
    public QueryWrapper getQuerywrapper(UserQueryRequest userQueryRequest) {
        if(userQueryRequest == null){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"参数为空");
        }
       return QueryWrapper.create()
                .eq(User::getId, userQueryRequest.getId())
                .eq(User::getUserRole, userQueryRequest.getUserRole())
                .like(User::getUserAccount, userQueryRequest.getUserAccount())
                .like(User::getUserName, userQueryRequest.getUserName())
                .like(User::getUserProfile, userQueryRequest.getUserProfile());

    }


    @Override
    public String getEncryptedPassword(String userPassword){
        //盐值
        final String salt = "1a2b3c4d";
        return DigestUtils.md5DigestAsHex((salt + userPassword).getBytes());
    }
}
